<html>
<head>
  <title>Evernote Export</title>
  <basefont face="微软雅黑" size="2" />
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta name="exporter-version" content="YXBJ Windows/601935 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;"/>
  <style>
    body, td {
      font-family: 微软雅黑;
      font-size: 12pt;
    }
  </style>
</head>
<body>
<a name="4027"/>
<h1>Tomcat 与 Nginx</h1>
<div>
<table bgcolor="#D4DDE5" border="0">
<tr><td><b>更新时间：</b></td><td><i>2020/6/13 20:45</i></td></tr>
<tr><td><b>作者：</b></td><td><i>#ShiH..</i></td></tr>
</table>
</div>
<br/>

<div>
<span><div><div><span style="font-size: 24px;">一、【 任务一：Tomcat 高级使用与原理剖析 】</span></div><div><span style="font-size: 18pt;">    1、对 Tomcat 服务器的初步认知和理解</span></div><div><span style="font-size: 18pt;">         </span><span style="font-size: 18pt;"><img src="Tomcat 与 Nginx 笔记_files/Image.png" type="image/png" data-filename="Image.png"/></span></div><div><br/></div><div><span style="font-size: 18pt;">    2、Tomcat 服务器， 可以同时运行管理多个项目（不同的站点对应不同的项目，端口都是 8080）；</span></div><div><span style="font-size: 18pt;">         PS：需要配置DNS域名解析，匹配域名所对应的服务器IP地址；</span></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font style="font-size: 12pt;"><font face="Consolas">    【说明】：</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">        1、appBase：指明项目所在的文件路径（此处为相对路径，相对于 conf/server.xml 而言，处于和 conf 文件夹同级的 webapps 文件夹中）；</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">        2、host节点里面没有配置任何内容的话，默认项目名为 ROOT 的项目；</font></font></div></div><div><span style="font-size: 18pt;"><br/></span></div><div><span style="font-size: 18pt;">         </span><span style="font-size: 18pt;"><img src="Tomcat 与 Nginx 笔记_files/Image [1].png" type="image/png" data-filename="Image.png"/></span></div><div><font style="font-size: 18pt;"><br/></font></div><div><span style="font-size: 18pt;">    3、同一个虚拟主机域名，依然可以运行管理多个项目，此时需要使用 URL 做进一步判定，访问的是哪一个项目；</span></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font face="Consolas"><font face="Consolas" style="font-size: 12pt;">&lt;Host name=&quot;www.abc.com&quot; appBase=&quot;webapps&quot; unpackWARs=&quot;true&quot; </font><span style="font-size: 12pt; font-family: Consolas;">autoDeploy=&quot;true&quot;&gt;</span></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">    &lt;!--</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">        docBase：Web应⽤⽬录或者War包的部署路径。可以是绝对路径，也可以是相对于 Host appBase的</font><span style="font-family: Consolas; font-size: 12pt;">相对路径。</span></font></div><div style="font-size: 12pt;"><font face="Consolas">        path：Web应⽤的Context 路径。如果我们Host名为localhost， 则该web应⽤访问的根路径为：</font></div><div style="font-size: 12pt;"><font face="Consolas">        http://localhost:8080/root</font></div><div style="font-size: 12pt;">    --&gt;</div><div style="font-size: 12pt;">    &lt;Context <b><font color="#EB0073">docBase=&quot;/Users/yingdian/workspace/servers/ROOT&quot; path=&quot;/root&quot;</font></b>&gt;&lt;/Context&gt;</div><div style="font-size: 12pt;">    &lt;Valve </div><div style="font-size: 12pt;">        className=&quot;org.apache.catalina.valves.AccessLogValve&quot; </div><div style="font-size: 12pt;"><span style="font-size: 12pt;">        directory=&quot;logs&quot; </span><span style="font-size: 12pt;">prefix=&quot;localhost_access_log&quot; </span></div><div style="font-size: 12pt;"><span style="font-size: 12pt;">        suffix=&quot;.txt&quot; </span></div><div style="font-size: 12pt;"><span style="font-size: 12pt;">        pattern=&quot;%h %l %u %t &quot;%r&quot; %s %b&quot; /&gt;</span></div><div style="font-size: 12pt;">&lt;/Host&gt;</div></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font style="font-size: 12pt;"><font face="Consolas">    【说明】：</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">        1、docBase：项目所在文件夹的路径，可以是相对路径（相对于 host 标签中的 appBase），也可以是绝对路径；</font></font></div><div><font style="font-size: 12pt;"><font style="font-family: Consolas;">        2、path：对应 host 标签的 name 虚拟域名后，当 url 的内容为该值时，访问对应 docBase 文件夹下的指定项目名的项目（此处访问的是 </font></font>ROOT <font style="font-size: 12pt;"><font style="font-family: Consolas;">默认项目）；</font></font></div></div><div><font style="font-size: 18pt;"><br/></font></div><div><span style="font-size: 24px;">二、【 手写 MiniCat 】</span></div><div><span style="font-size: 18pt;">    1、手写 Mini 版 Tomcat V1.0 -- 关于 socket 通信的知识点回顾</span></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font face="Consolas"><font style="font-size: 12pt;">public void start() throws IOException {</font></font></div><div><font face="Consolas"><font style="font-size: 12pt;">    <font face="Consolas">// 设置 socket 通信时，对应的监听端口；</font></font></font></div><div><font face="Consolas"><font face="Consolas" style="font-size: 12pt;">    ServerSocket serverSocket = new ServerSocket(port);</font></font></div><div><font face="Consolas"><font face="Consolas" style="font-size: 12pt;">    System.out.println(&quot;====&gt; MiniCat start on port: &quot; + port);</font></font></div><div style="font-size: 12pt;"><div><font face="Consolas"><font face="Consolas"><br/></font></font></div></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">    while (true){</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">        // 阻塞式等待，直到接收到 socket 请求；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">        Socket socket = serverSocket.accept();</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">        /**</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">         * 关于 socket 通信：</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">         *      1、想要获取 socket 带过来的信息，需要使用 socket.getInputStream，将信息读入到 本地内存中；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">         *      2、想要把信息响应给请求方，需要使用 socket.getOutputStream，把要传递的信息放到这个 OutputStream 中即可；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">         *         write 之后，即可关闭 socket 连接，消息就已经发回给请求方了；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">         */</font></font></div><div style="font-size: 12pt;"><font face="Consolas">        OutputStream outputStream = socket.getOutputStream();</font></div><div style="font-size: 12pt;"><font face="Consolas">        outputStream.write(&quot;Hello MiniCat!&quot;.getBytes());</font></div><div style="font-size: 12pt;"><font face="Consolas">        socket.close();</font></div><div style="font-size: 12pt;"><font face="Consolas">    }</font></div><div style="font-size: 12pt;"><div><font face="Consolas"><br/></font></div></div><div style="font-size: 12pt;"><font face="Consolas">}</font></div></div><div><span style="font-size: 18pt;">    2、手写 Mini 版 Tomcat V2.0 -- 封装 Response 对象，并响应 静态资源文件；</span></div><div><span style="font-size: 18pt;">         </span><span style="font-size: 18pt;"><img src="Tomcat 与 Nginx 笔记_files/Image [2].png" type="image/png" data-filename="Image.png"/></span></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font face="Consolas" style="font-size: 12pt;">/**</font></div><div><font face="Consolas" style="font-size: 12pt;">* 获取资源的绝对路径；</font></div><div><font face="Consolas" style="font-size: 12pt;">* @param path</font></div><div><font face="Consolas" style="font-size: 12pt;">* @return</font></div><div><font face="Consolas" style="font-size: 12pt;">*【说明】：</font></div><div><font face="Consolas" style="font-size: 12pt;">*      1、resources 文件夹中的内容，最终都会放到 classes 文件夹中；</font></div><div><font face="Consolas" style="font-size: 12pt;">*      2、src/main/java 中写的所有代码，最终也都会放到 classes 文件夹中；</font></div><div><font face="Consolas" style="font-size: 12pt;">*      3、所以可以通过任意类的 class 对象，获取到其保存的根目录 classes 文件夹的绝对路径；</font></div><div><font face="Consolas" style="font-size: 12pt;">*      4、最后防止操作系统不同的问题，处理一下 文件目录的连接符问题；</font></div><div><font face="Consolas" style="font-size: 12pt;">*/</font></div><div><font face="Consolas" style="font-size: 12pt;">public static String getAbsolutePath(String path){</font></div><div><font face="Consolas" style="font-size: 12pt;">    String absolutePath = StaticResourceUtil.class.getResource(&quot;/&quot;).getPath();</font></div><div><font face="Consolas" style="font-size: 12pt;">    return absolutePath.replaceAll(&quot;\\\\&quot;,&quot;/&quot;) + path;</font></div><div><font face="Consolas" style="font-size: 12pt;">}</font></div></div><div><span style="font-size: 18pt;">    3、使用 dom4j 和 jaxen 解析 xml 文件</span></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font><font face="Consolas" style="font-size: 12pt;">/**</font></font></div><div><font><font face="Consolas" style="font-size: 12pt;">* 加载 web.xml 中配置的 servlet 映射关系</font></font></div><div><font><font face="Consolas" style="font-size: 12pt;">*【说明】：</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">*      1、通过任意类的 class 对象，获取到 classLoader 后，也就定位到了 classes 文件夹；</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">*      2、然后从中 getResourcesAsStream 是以 classes 文件夹为相对路径，读取相关文件 并转化为 io 流；</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">*/</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">private void loadServlet() throws DocumentException {</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">    // 1、获取到要解析的 xml 文件的 io 流；</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">    InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(&quot;web.xml&quot;);</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">    // 2、创建 SAXReader 来解析 xml 文件；</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">    SAXReader saxReader = new SAXReader();</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">    // 3、传入 io 流，即可获取得到 Document 对象；</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">    Document document = saxReader.read(resourceAsStream);</font></font></div><div style="font-size: 12pt;"><div><font><font face="Consolas"><br/></font></font></div></div><div style="font-size: 12pt;"><font><font face="Consolas">    Element rootElement = document.getRootElement();</font></font></div><div style="font-size: 12pt;"><div><font><font face="Consolas"><br/></font></font></div></div><div style="font-size: 12pt;"><font><font face="Consolas">    // 4、获取到根节点下的所有 servlet 节点；</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">    List&lt;Element&gt; selectNodes = rootElement.selectNodes(&quot;//servlet&quot;);</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">    for(Element element:selectNodes){</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">        Element servletNameEle = (Element) element.selectSingleNode(&quot;servlet-name&quot;);</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">        Element servletClassEle = (Element) element.selectSingleNode(&quot;servlet-class&quot;);</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">        String servletName = servletNameEle.getStringValue();</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">        String servletClass = servletClassEle.getStringValue();</font></font></div><div style="font-size: 12pt;"><div><font><font face="Consolas"><br/></font></font></div></div><div style="font-size: 12pt;"><font><font face="Consolas">        // 匹配到对应 servlet-name 的那个 servlet-mapping 标签节点；</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">        Element singleNode = (Element) rootElement.selectSingleNode(&quot;/web-app/servlet-mapping[servlet-name='&quot; + servletName + &quot;']&quot;);</font></font></div><div style="font-size: 12pt;"><font><font face="Consolas">        String urlPattern = singleNode.selectSingleNode(&quot;url-pattern&quot;).getStringValue();</font></font></div><div style="font-size: 12pt;"><div><font><font face="Consolas"><br/></font></font></div></div><div style="font-size: 12pt;"><font><font face="Consolas">        // 维护一个 Map&lt;url-pattern,servletClass&gt;</font></font></div><div style="font-size: 12pt;"><font>        try {</font></div><div style="font-size: 12pt;"><font>            servletMap.put(urlPattern, (HttpServlet) Class.forName(servletClass).newInstance());</font></div><div style="font-size: 12pt;"><font>        } catch (InstantiationException e) {</font></div><div style="font-size: 12pt;"><font>            e.printStackTrace();</font></div><div style="font-size: 12pt;"><font>        } catch (IllegalAccessException e) {</font></div><div style="font-size: 12pt;"><font>            e.printStackTrace();</font></div><div style="font-size: 12pt;"><font>        } catch (ClassNotFoundException e) {</font></div><div style="font-size: 12pt;"><font>            e.printStackTrace();</font></div><div style="font-size: 12pt;"><font>        }</font></div><div style="font-size: 12pt;"><div><font><br/></font></div></div><div style="font-size: 12pt;"><font>    }</font></div><div style="font-size: 12pt;"><div><font><br/></font></div></div><div style="font-size: 12pt;"><font>}</font></div></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font style="font-size: 12pt;"><font face="Consolas">【说明】：</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">    1、dom4j 和 xpath 解析还有待加强：如 Element、Node 对象的使用，xpath 表达式定位标签元素；</font></font></div></div><div><span style="font-size: 18pt;">    4、将 socket.getInputStream() 获取到的内容进行响应处理的操作，放到线程中执行；</span></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font><font face="Consolas" style="font-size: 12pt;">/**</font></font></div><div><font><font face="Consolas" style="font-size: 12pt;">* V3.0：优化改造 -- 多线程处理请求；</font></font></div><div><font><font face="Consolas" style="font-size: 12pt;">* 使用多线程进行改造：先考虑直接在当前方法中进行多线程改造，然后再考虑将操作提取出来到一个类中；</font></font></div><div><font><font face="Consolas" style="font-size: 12pt;">*/</font></font></div><div style="font-size: 12pt;"><font>while (true){</font></div><div style="font-size: 12pt;"><font>    Socket socket = serverSocket.accept();</font></div><div style="font-size: 12pt;"><font>    RequestProcessor requestProcessor = new RequestProcessor(socket, servletMap);</font></div><div style="font-size: 12pt;"><font>    requestProcessor.start();</font></div><div style="font-size: 12pt;"><font>}</font></div></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font face="Consolas" style="font-size: 12pt;">/**</font></div><div><font face="Consolas" style="font-size: 12pt;">* 创建多线程来处理用户的 request 请求；</font></div><div><font face="Consolas" style="font-size: 12pt;">*/</font></div><div><font face="Consolas" style="font-size: 12pt;">public class RequestProcessor extends Thread {</font></div><div><font face="Consolas" style="font-size: 12pt;"><br/></font></div><div><font face="Consolas" style="font-size: 12pt;">    private Socket socket;</font></div><div><font face="Consolas" style="font-size: 12pt;">    private Map&lt;String,HttpServlet&gt; servletMap;</font></div><div><font face="Consolas" style="font-size: 12pt;"><br/></font></div><div><font face="Consolas" style="font-size: 12pt;">    public RequestProcessor(Socket socket,Map&lt;String,HttpServlet&gt; servletMap){</font></div><div><font face="Consolas" style="font-size: 12pt;">        this.socket = socket;</font></div><div><font face="Consolas" style="font-size: 12pt;">        this.servletMap = servletMap;</font></div><div><font face="Consolas" style="font-size: 12pt;">    }</font></div><div><font face="Consolas" style="font-size: 12pt;"><br/></font></div><div><font face="Consolas" style="font-size: 12pt;">    @Override</font></div><div><font face="Consolas" style="font-size: 12pt;">    public void run() {</font></div><div><font face="Consolas" style="font-size: 12pt;">        try {</font></div><div><font face="Consolas" style="font-size: 12pt;">            // 获取请求带过来的所有信息，通过 socket.getInputStream 获取；</font></div><div><font face="Consolas" style="font-size: 12pt;">            InputStream inputStream = socket.getInputStream();</font></div><div><font face="Consolas" style="font-size: 12pt;"><br/></font></div><div><font face="Consolas" style="font-size: 12pt;">            // 封装 Request、Response 对象；</font></div><div><font face="Consolas" style="font-size: 12pt;">            Request request = new Request(inputStream);</font></div><div><font face="Consolas" style="font-size: 12pt;">            Response response = new Response(socket.getOutputStream());</font></div><div><font face="Consolas" style="font-size: 12pt;"><br/></font></div><div><font face="Consolas" style="font-size: 12pt;">            if(servletMap.get(request.getUrl())==null){</font></div><div><font face="Consolas" style="font-size: 12pt;">                // 响应 HTML 静态页面；</font></div><div><font face="Consolas" style="font-size: 12pt;">                response.outputHtml(request.getUrl());</font></div><div><font face="Consolas" style="font-size: 12pt;">            }else {</font></div><div><font face="Consolas" style="font-size: 12pt;">                // 响应 动态资源的请求；</font></div><div><font face="Consolas" style="font-size: 12pt;">                HttpServlet httpServlet = servletMap.get(request.getUrl());</font></div><div><font face="Consolas" style="font-size: 12pt;">                httpServlet.service(request,response);</font></div><div><font face="Consolas" style="font-size: 12pt;">            }</font></div><div><font face="Consolas" style="font-size: 12pt;"><br/></font></div><div><font face="Consolas" style="font-size: 12pt;">            socket.close();</font></div><div><font face="Consolas" style="font-size: 12pt;">        }catch (Exception e){</font></div><div><font face="Consolas" style="font-size: 12pt;">            e.printStackTrace();</font></div><div><font face="Consolas" style="font-size: 12pt;">        }</font></div><div><font face="Consolas" style="font-size: 12pt;"><br/></font></div><div><font face="Consolas" style="font-size: 12pt;">    }</font></div><div><font face="Consolas" style="font-size: 12pt;">}</font></div></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font style="font-size: 12pt;"><font face="Consolas">【说明】：</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">    1、先理解方法调用，然后涉及到对象的统一，所以会有对象的传参；</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">    2、然后需要将目标执行的方法，抛给线程去执行；</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">    3、最终可以提取出一个线程类，来完全实现上面的功能；</font></font></div></div><div><span style="font-size: 18pt;">    5、理解线程池的使用</span></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font face="Consolas"><font face="Consolas" style="font-size: 12pt;">// **创建线程池**</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">int corePoolSize = 10;  // 核心大小：始终保持活跃的线程个数；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">int maximumPoolSize = 50;   // 最大线程数；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">long keepAliveTime = 100l;  // 线程保留时间，超出该时间未被使用，就将被销毁；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">TimeUnit unit = TimeUnit.SECONDS;   // 设置时间的单位；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">BlockingQueue&lt;Runnable&gt; workQueue = new ArrayBlockingQueue&lt;&gt;(50);   // 设置排队阻塞的队列长度；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 线程工厂；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();    // 处理执行的策略；</font></font></div><div style="font-size: 12pt;"><div><font face="Consolas"><br/></font></div></div><div style="font-size: 12pt;"><font face="Consolas">ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(</font></div><div style="font-size: 12pt;"><font face="Consolas">        corePoolSize,</font></div><div style="font-size: 12pt;"><font face="Consolas">        maximumPoolSize,</font></div><div style="font-size: 12pt;"><font face="Consolas">        keepAliveTime,</font></div><div style="font-size: 12pt;"><font face="Consolas">        unit,</font></div><div style="font-size: 12pt;"><font face="Consolas">        workQueue,</font></div><div style="font-size: 12pt;"><font face="Consolas">        threadFactory,</font></div><div style="font-size: 12pt;"><font face="Consolas">        handler</font></div><div style="font-size: 12pt;"><font face="Consolas">);</font></div><div style="font-size: 12pt;"><div><font face="Consolas"><br/></font></div></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">/**</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">* V3.0：优化改造 -- 多线程处理，使用线程池进行改造</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">*/</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">while (true){</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">    Socket socket = serverSocket.accept();</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">    RequestProcessor requestProcessor = new RequestProcessor(socket, servletMap);</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">    // requestProcessor.start();</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">    // 把线程对象（因为传参不同，所以还是需要线程对象的）丢给 线程池，让线程池中的线程去执行 线程类中的 run 方法；</font></font></div><div style="font-size: 12pt;"><font face="Consolas"><font face="Consolas">    threadPoolExecutor.execute(requestProcessor);</font></font></div><div style="font-size: 12pt;"><font face="Consolas">}</font></div></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font style="font-size: 12pt;"><font face="Consolas">【说明】：</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">    1、创建好一个指定规模、指定配置的线程池，里面有许多的线程；</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">    2、然后需要自己手动创建好相关的线程类，因为里面执行的内容可能会有不同，所以线程类需要自己创建；</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">    3、把线程类丢给线程池后，线程池里的线程，将会执行线程类中的 run 方法；</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">    PS：本质上来说，线程的创建不是由我们来执行的，我们只需要告知相应的线程类即可（传参不同，实际调用 run 方法时也就不同），线程池会自动让线程去执行其中的 run 方法;换句话说，使用线程池，就是省去了频繁的创建线程、销毁线程的这么一个资源浪费的过程而已；</font></font></div></div><div><font style="font-size: 18pt;"><br/></font></div><div><span style="font-size: 24px;">三、【 </span><span style="font-size: 24px;">Tomcat 源码剖析和调优</span> <span style="font-size: 24px;">】</span></div><div><span style="font-size: 18pt;">    1、</span> <span style="font-size: 18pt;">启动流程时序图解读  及  容器生命周期管理机制</span></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font face="Consolas" style="font-size: 12pt;">PS：源码部分的解析，有待加强，暂时只做简单了解熟悉即可；</font></div><div><font face="Consolas" style="font-size: 12pt;">【补充】：后续要去解析其设计架构的思路，以及具体代码实现过程中的技术知识点的总结；</font></div></div><div><span style="font-size: 18pt;">    2、</span> <span style="font-size: 18pt;">Tomcat类加载机制  之  JVM类加载机制回顾</span></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.15);-en-codeblock:true;"><div><font style="font-size: 12pt;"><font face="Consolas">【说明】：</font></font></div><div><font style="font-size: 12pt;"><font face="Consolas">    目前此部分知识也只做简单的了解；</font></font></div></div><div><font style="font-size: 18pt;"><br/></font></div><hr/><div><font style="font-size: 18pt;"><br/></font></div><div><font style="font-size: 18pt;"><br/></font></div><div><font style="font-size: 18pt;"><br/></font></div></div></span>
</div></body></html> 